using System;
using System.Collections;
using System.Collections.Generic;

namespace Jonathan.SharpDB
{
    public class Results
    {
        #region - Variables -

        /// <summary>
        /// Collection of Columns...
        /// </summary>
        private List<Column> m_Cols;

        /// <summary>
        /// Collection of Rows...
        /// </summary>
        private List<ArrayList> m_Rows;

        #endregion

        public Results()
        {
			this.m_Cols = new List<Column>();
			this.m_Rows = new List<ArrayList>();
        }

        /// <summary>
        /// Gets an ArrayList that contains the Columns of the Results...
        /// </summary>
		public List<Column> Columns
        {
            get { return this.m_Cols; }
        }

        /// <summary>
        /// Gets an ArrayList that contains the Rows of the Results...
        /// </summary>
		public List<ArrayList> Rows
        {
            get { return this.m_Rows; }
        }

        /// <summary>
        /// Gets the value at the given column and row...
        /// </summary>
        /// <param name="col">Column index.</param>
        /// <param name="row">Row index.</param>
        /// <returns>Value at coordinates.</returns>
        public object GetField(int col, int row)
        {
            if (this.m_Rows.Count > row)
            {
                ArrayList r = this.m_Rows[row];

                if (r.Count > col)
                {
                    return r[col];
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Gets the value at the given column and row...
        /// </summary>
        /// <param name="col">Column index.</param>
        /// <param name="row">Row index.</param>
        /// <returns>Value at coordinates.</returns>
        public string GetFieldString(int col, int row)
        {
            if (this.m_Rows.Count > row)
            {
                ArrayList r = this.m_Rows[row];

                if (r.Count > col)
                {
                    return r[col].ToString();
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Gets the value at the given column and row...
        /// </summary>
        /// <param name="col">Column index.</param>
        /// <param name="row">Row index.</param>
        /// <returns>Value at coordinates.</returns>
        public int GetFieldInt(int col, int row)
        {
            if (this.m_Rows.Count > row)
            {
                ArrayList r = this.m_Rows[row];

                if (r.Count > col)
                {
                    return Convert.ToInt32(r[col]);
                }
                else
                {
                    return -1;
                }
            }
            else
            {
                return -1;
            }
        }

        /// <summary>
        /// Gets the value at the given column and row...
        /// </summary>
        /// <param name="col">Column index.</param>
        /// <param name="row">Row index.</param>
        /// <returns>Value at coordinates.</returns>
        public decimal GetFieldDecimal(int col, int row)
        {
            if (this.m_Rows.Count > row)
            {
                ArrayList r = this.m_Rows[row];

                if (r.Count > col)
                {
                    return Convert.ToDecimal(r[col]);
                }
                else
                {
                    return Convert.ToDecimal(-1);
                }
            }
            else
            {
                return Convert.ToDecimal(-1);
            }
        }

        /// <summary>
        /// Gets the value at the given column and row...
        /// </summary>
        /// <param name="col">Column index.</param>
        /// <param name="row">Row index.</param>
        /// <returns>Value at coordinates.</returns>
        public DateTime GetFieldDateTime(int col, int row)
        {
            if (this.m_Rows.Count > row)
            {
                ArrayList r = this.m_Rows[row];

                if (r.Count > col)
                {
                    return DateTime.Parse(r[col].ToString());
                }
                else
                {
                    return DateTime.Now; ;
                }
            }
            else
            {
                return DateTime.Now;
            }
        }

        /// <summary>
        /// Gets the Count of the Rows in the Results...
        /// </summary>
        public int RowCount
        {
            get { return this.m_Rows.Count; }
        }
        
        /// <summary>
        /// Add a column with the given Name and Type...
        /// </summary>
        /// <param name="columnName">Name of Column.</param>
        /// <param name="columnType">Type of Column.</param>
        /// <returns>DBMessage</returns>
        internal void AddColumn(string columnName, ColumnType columnType)
        {
            // Look for a column with the same name...
            foreach (Column col in m_Cols)
            {
                if (col.ColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase))
                {
                    return;
                }
            }

            // Create and add a new column...
            this.m_Cols.Add(new Column(columnName, columnType));
        }

        /// <summary>
        /// Adds a row to the Results
        /// </summary>
        /// <param name="row">Row to add</param>
        internal void AddRow(ArrayList row)
        {
            this.m_Rows.Add(row);
        }

        internal void Sort(string colName, SortDirection dir)
        {
            int index = -1;
            ColumnType type = ColumnType.STRING;

            for(int a = 0; a < this.m_Cols.Count; a++)
            {
                Column col = this.m_Cols[a];
                if(col.ColumnName.Equals(colName, StringComparison.CurrentCultureIgnoreCase))
                {
                    index = a;
                    type = col.ColumnType;
                    break;
                }
            }

            if (index != -1 && type != ColumnType.STREAM)
            {
                this.m_Rows.Sort(new RowSorter(dir, index, type));
            }
        }
    }
}
